package com.prs.crm.report;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.AbstractDataset;
import org.jfree.data.general.DefaultPieDataset;

import com.prs.crm.context.Constrains;
import com.prs.crm.domain.crm.Customer;
import com.prs.crm.domain.crm.CustomerTrade;
import com.prs.crm.domain.crm.CustomerType;
import com.prs.crm.domain.crm.Liaison;
import com.prs.crm.domain.hr.Person;

public class ChartServiceImpl extends Chart3D implements ChartService {
	
	private Integer width = 650;
	private Integer height = 320;
	
	public ChartResult export(final AbstractDataset dataset,final String title,final String hoturl){
		ChartRenderingInfo renderingInfo = new ChartRenderingInfo(new StandardEntityCollection());
		ChartResult cr = new ChartResult();
		try {
			JFreeChart chart = this.getPieChart3D((DefaultPieDataset)dataset, title, hoturl);
			String filename = ReportUtils.saveChartAsPNG(chart, this.getWidth(), this.getHeight(), renderingInfo, this.getSession());
			String imgurl = this.getRequest().getContextPath()+ReportUtils.getTmpPath()+"/"+filename;
			cr.setImgPath("<img src=\""+imgurl+"\" border=0 usemap=\"#map0\" />");
			cr.setHotMaps(this.getHotImageMaps("map0", renderingInfo));
			return cr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public ChartResult export(final AbstractDataset dataset, final String title, final String leftTitle, final String type, final String hotUrl){
		ChartRenderingInfo renderingInfo = new ChartRenderingInfo(new StandardEntityCollection());
		ChartResult cr = new ChartResult();
		JFreeChart chart = this.getHotBarChart3D((DefaultCategoryDataset)dataset, title, leftTitle, type, hotUrl);
		try {
			String filename = ReportUtils.saveChartAsPNG(chart, this.getWidth(), this.getHeight(), renderingInfo, this.getSession());
			String imgurl = this.getRequest().getContextPath()+ReportUtils.getTmpPath()+"/"+filename;
			cr.setImgPath("<img src=\""+imgurl+"\" border=0 usemap=\"#map0\" />");
			cr.setHotMaps(this.getHotImageMaps("map0", renderingInfo));
			return cr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	public ChartResult exportLineChart(AbstractDataset dataset, String title,
			String leftTitle, String type, String hotUrl) {
		ChartRenderingInfo renderingInfo = new ChartRenderingInfo(new StandardEntityCollection());
		ChartResult cr = new ChartResult();
		JFreeChart chart = this.getLineChart((DefaultCategoryDataset)dataset, title, leftTitle, type, hotUrl);
		try {
			String filename = ReportUtils.saveChartAsPNG(chart, this.getWidth(), this.getHeight(), renderingInfo, this.getSession());
			String imgurl = this.getRequest().getContextPath()+ReportUtils.getTmpPath()+"/"+filename;
			cr.setImgPath("<img src=\""+imgurl+"\" border=0 usemap=\"#map0\" />");
			cr.setHotMaps(this.getHotImageMaps("map0", renderingInfo));
			return cr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	public HttpSession getSession(){
		return this.getRequest().getSession();
	}
	public HttpServletRequest getRequest(){
		return ServletActionContext.getRequest();
	}
	public Integer getWidth() {
		return width;
	}
	public void setWidth(final Integer width) {
		this.width = width;
	}
	public Integer getHeight() {
		return height;
	}
	public void setHeight(final Integer height) {
		this.height = height;
	}

	public AbstractDataset fillDataset(Collection<Object[]> dataList,
			int GraphicsType) {
		AbstractDataset Dataset = null;
		if(GraphicsType == Constrains.REPORT_PIECHART)
			Dataset = new DefaultPieDataset();
		else if(GraphicsType == Constrains.REPORT_BARCHART)
			Dataset = new DefaultCategoryDataset();
		
		for(Object[] o : dataList){
			String name = "";
			Number count = 0;
			Integer id = 0;
			for(Object value : o){
				if(value != null){
					if(value instanceof Person){
						name = ((Person) value).getResume().getName();
						id = ((Person) value).getId();
					}else if(value instanceof CustomerType){
						name = ((CustomerType) value).getName();
						id = ((CustomerType) value).getId();
					}else if(value instanceof CustomerTrade){
						name = ((CustomerTrade) value).getName();
						id = ((CustomerTrade) value).getId();
					}else if(value instanceof Number) {
						count = (Number)value;
					}
				}
			}
			if(!name.equals("")){
				if(GraphicsType == Constrains.REPORT_PIECHART)
					((DefaultPieDataset)Dataset).setValue(name+"["+id+"]", count);
				else if(GraphicsType == Constrains.REPORT_BARCHART)
					((DefaultCategoryDataset)Dataset).addValue(count, name, name+"["+id+"]");
			}
		}
		return Dataset;
	}
	public Person getPerson(String series) {
		Person person = new Person();
		if(series.indexOf("[") != -1 && series.indexOf("]") != -1)
			person.setId(Integer.parseInt(series.substring(series.indexOf("[")+1, series.indexOf("]"))));
		else
			person.setId(0);
		return person;
	}
	public Collection<Person> convertIdsToPersons(Collection<Integer> ids){
		Collection<Person> persons = new ArrayList<Person>();
		for(Integer id : ids){
			Person person = new Person();
			person.setId(id);
			persons.add(person);
		}
		return persons;
	}
	
	public Collection<Date> add(Collection<Date> lists, Date dates){
		if(lists != null){
			lists.add(dates);
			return lists;
		}else{
			Collection<Date> listTimes = new ArrayList<Date>();
			listTimes.add(dates);
			return listTimes;
		}
	}
	
	@SuppressWarnings("unchecked")
	public AbstractDataset fillLineChartSouce(Collection<?> dataSouce, Integer type, int chartType, String oldYear, String month) {
		Map<String, Collection<Date>> nameDatas = new TreeMap<String, Collection<Date>>();
		for(Liaison lian : (Collection<Liaison>)dataSouce){
			String customerName = lian.getRecorder().getResume().getName();
			nameDatas.put(customerName, this.add(nameDatas.get(customerName), lian.getLiaisonTime()));
		}
		if(chartType == Constrains.REPORT_BARCHART)
			return fillAbstractDataset(nameDatas, type, oldYear, month);
		else
			return fillAbstractDatasetpie(nameDatas, type, oldYear, month);
	}
	
	public AbstractDataset fillAbstractDatasetpie(Map<String, Collection<Date>> maps, Integer type, String oldYear, String month){
		DefaultPieDataset dataSet = new DefaultPieDataset();
		for(String key : maps.keySet()){
			Collection<Date> tempDates = maps.get(key);
			Map<Integer, Integer> counts = null;
			if(type == 1){
				counts = this.getMonthByYear(tempDates);
				for(Integer id : counts.keySet()){
					dataSet.setValue(id + "月",counts.get(id));
				}
			}else if(type == 2){
				counts = this.getDaysWeeks(tempDates, Integer.parseInt(oldYear), Integer.parseInt(month));
				for(Integer id : counts.keySet()){
					dataSet.setValue(id + "周",counts.get(id));
				}
			}
		}
		return dataSet;
	}
	
	
	public AbstractDataset fillAbstractDataset(Map<String, Collection<Date>> maps, Integer type, String oldYear, String month){
		DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
		for(String key : maps.keySet()){
			Collection<Date> tempDates = maps.get(key);
			Map<Integer, Integer> counts = null;
			if(type == 1){
				counts = this.getMonthByYear(tempDates);
				for(Integer id : counts.keySet()){
					dataSet.addValue(counts.get(id), key, id + "月");
				}
			}else if(type == 2){
				counts = this.getDaysWeeks(tempDates, Integer.parseInt(oldYear), Integer.parseInt(month));
				for(Integer id : counts.keySet()){
					dataSet.addValue(counts.get(id), key, id + "周");
				}
			}
		}
		return dataSet;
	}
	
	@SuppressWarnings("unchecked")
	public AbstractDataset fillAbstractDataset(Map maps, int chartType, String unit, String singleKey){
		AbstractDataset data = chartType == Constrains.REPORT_PIECHART ? new DefaultPieDataset() : new DefaultCategoryDataset();
		for(Object key : maps.keySet()){
			if(chartType == Constrains.REPORT_PIECHART){
				((DefaultPieDataset)data).setValue(key.toString() + unit, (Number)maps.get(key));
			}else {
				((DefaultCategoryDataset)data).addValue((Number)maps.get(key), singleKey == null ? key.toString() + unit : singleKey, key.toString() + unit);
			}
		}
		return data;
	}

	@Override
	public AbstractDataset fillCustomerAddLine(Collection<Customer> dataSouce,
			Integer type, String oldYear, String month, int chartType, String singleKey) {
		Collection<Date> dateList = new ArrayList<Date>();
		for(Customer cus : dataSouce){
			dateList.add(cus.getRecordTime());
		}
		if(type == 1){
			return fillAbstractDataset(getMonthByYear(dateList), chartType,"月", singleKey);
		}else {
			return fillAbstractDataset(getDaysWeeks(dateList, Integer.parseInt(oldYear), Integer.parseInt(month)), chartType, "周", singleKey);
		}
		
	}
	
	
}
